Skip to main content
Version: 12.10.0

Guidelines

Spring boot Guidelines for Navida pro

Controller

Use interface to define the controller end points and make sure each controller is annotated for the version path


@RequestMapping("/api/v1")
public interface IUserCommonController {

@Operation(summary = "Save users bookmarks", description = "", security = {
@SecurityRequirement(name = "JWT") }, tags = { "UserOperations" })
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Save users bookmarks",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = SelectedFavouritesDTO.class))),

@ApiResponse(responseCode = "400", description = "Bad Request"),

@ApiResponse(responseCode = "401", description = "Unauthorized"),

@ApiResponse(responseCode = "403", description = "Forbidden"),

@ApiResponse(responseCode = "500", description = "Internal server error") })
@PostMapping(value = "/user-ops/bookMark", produces = { "application/json" }, consumes = {
"application/json" })

ResponseEntity<Favourites> userBookmarkPost(SelectedFavouritesDTO selectedFavouritesDTO);

}

@RequestMapping("/api/v1") public interface IUserCommonController -> this will help us to control the version inside the code, for different versions , you can just replicate the controller class annotated with a different version and make the changes, In a way the application can support multiple versions easily

Guidelines for Logging Sensitive Information

Developers need to follow the logging governance practices that align with client's expectation.

Avoid logging sensitive information at the log.info level. Any such statements must be either removed or moved to log.debug for debugging purposes.Developers must adhere these guidelines during development activities. This is to ensure sensitive informations are not logged.

  1. User-related information: User ID, first names, addresses, dates of birth, Insurance related information etc.

  2. Configuration-related information: Database details, Kafka server information, trust store locations, third-party URLs, etc.

Follow the structure for Swagger and OpenTelemetry

API Request and response body

use camelCase for column name

Wrong one

        @JsonProperty(name = "tenant_id")
private String tenantId;

Correct one

        @JsonProperty(name = "tenantId")
private String tenantId;

Project Structure

src/main/java/: Contains your Java source files.
src/main/resources/: Contains resources such as properties files.
src/test/java/: Contains your test source files.

Naming Conventions

Packages: Lowercase and use reverse domain name notation (e.g., com.example.projectname). Classes: UpperCamelCase and be descriptive (e.g., UserController, ApplicationService). Methods: lowerCamelCase and reflect the action (e.g., getUser, saveUser).

Maven Dependencies

Include the following dependencies in your pom.xml for a REST API project:

<dependencies>
<!-- Spring Boot Starter Web for REST API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- (Optional) Spring Boot Starter Data JPA for database operations -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- (Optional) Spring Boot Starter Security for authentication and authorization -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Other dependencies as needed -->
</dependencies>

Application Properties

Set application properties in src/main/resources/application.properties:

# Server port
server.port=8080

# Database configuration (if using JPA)
spring.datasource.url=jdbc:mysql://localhost:3306/dbname
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.jpa.hibernate.ddl-auto=update

Security settings (if using Spring Security)

Logging settings

logging.level.org.springframework.web=INFO REST Controllers Annotate controllers with @RestController. Use @RequestMapping to define the base path. Use HTTP verbs to define actions: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping. Example:

@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAll();
return ResponseEntity.ok(users);
}

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}

// Additional endpoints as needed...
}

Service Layer

Encapsulate business logic in service classes. Annotate services with @Service. Example:

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public List<User> findAll() {
return userRepository.findAll();
}

public User save(User user) {
return userRepository.save(user);
}

// Additional methods as needed...
}

Data Access Layer

Use Spring Data JPA repositories for data access. Extend JpaRepository or CrudRepository. Example:

public interface UserRepository extends JpaRepository<User, Long> {
// Custom query methods as needed...
}

Exception Handling

Use @ControllerAdvice to handle exceptions globally. Use @ExceptionHandler to define custom exception handling. Example:

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleResourceNotFoundException(ResourceNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}

// Additional exception handlers as needed...
}

Validation

Use JSR-303/JSR-380 annotations for validation (@NotNull, @Size, @Valid, etc.). Annotate controller method parameters with @Valid to enable validation. Example:

@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}

Testing

Write unit tests for service layer using JUnit and Mockito. Write integration tests for controllers using @SpringBootTest and TestRestTemplate or MockMvc. Example:

@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

@Autowired
private MockMvc mockMvc;

// Test cases...
}

Documentation

Use Swagger/OpenAPI for API documentation. Include springdoc-openapi-ui dependency in pom.xml. Example:

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>

Security

Secure endpoints using Spring Security. Configure authentication and authorization as needed. Example:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic(); // or use formLogin(), oauth2Login(), etc.
}

// Additional security configurations...
}

Logging

Use SLF4J for logging. Log important events and exceptions. Example:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserService {

private static final Logger logger = LoggerFactory.getLogger(UserService.class);

public User save(User user) {
logger.info("Saving user: {}", user);
// ...
}
}